package main

// 默认的布隆拦截器的size
const DEFAULT_SIZE = 1 << 30

// 默认的cache数组
var DEFAULT_CACHE = make([]int, DEFAULT_SIZE, DEFAULT_SIZE)

// 默认的seeds数组
var DEFAULT_SEEDS = []int{31, 33, 37, 39, 41}

// 默认的hash工具类
var DEFAULT_HASH []SimpleHash

// 初始化
func init() {
	hash31 := SimpleHash{31}
	hash33 := SimpleHash{33}
	hash37 := SimpleHash{37}
	hash39 := SimpleHash{39}
	hash41 := SimpleHash{41}
	DEFAULT_HASH = []SimpleHash{hash31, hash33, hash37, hash39, hash41}
}

// 布隆拦截器
type BloomFilter struct {
	cache []int
	seeds []int
	hash  []SimpleHash
}

// add方法
func (b BloomFilter) private_addValue(value string) {
	for i := 0; i < len(b.hash); i++ {
		hashcode := b.hash[i].hashCode(value)
		index := hashcode % len(b.cache)
		b.cache[index] |= (1 << hashcode)
	}
}

// add方法的入口
func (b BloomFilter) Public_add(value string) {
	if 0 != len(value) {
		b.private_addValue(value)
	}
}

// 是否存在
func (b BloomFilter) Public_contains(value string) bool {
	if 0 == len(value) {
		return false
	}
	var result bool = true
	for i := 0; i < len(b.hash); i++ {
		hashcode := b.hash[i].hashCode(value)
		index := hashcode % len(b.cache)
		result = result && ((b.cache[index] & (1 << hashcode)) != 0)
	}
	return result
}

func Public_initBloomFilter() BloomFilter {
	return Public_initBloomFilterAllArgs(DEFAULT_CACHE, DEFAULT_SEEDS, DEFAULT_HASH)
}

func Public_initBloomFilterBySize(size int) BloomFilter {
	return Public_initBloomFilterAllArgs(make([]int, size, size), DEFAULT_SEEDS, DEFAULT_HASH)
}

func Public_initBloomFilterBySeeds(seeds []int) BloomFilter {
	var hash []SimpleHash
	for i := range seeds {
		hash = append(hash, SimpleHash{i})
	}
	return Public_initBloomFilterAllArgs(DEFAULT_CACHE, seeds, hash)
}

// 全参构造器
func Public_initBloomFilterAllArgs(cache []int, seed []int, hash []SimpleHash) BloomFilter {
	var result BloomFilter
	result.cache = cache
	result.seeds = seed
	result.hash = hash
	return result
}

//func main() {
//	bloomFilter := Public_initBloomFilter()
//	bloomFilter.Public_add("1")
//	fmt.Println(bloomFilter.Public_contains("1"))
//	fmt.Println(bloomFilter.Public_contains("ad"))
//	bloomFilter.Public_add("ad")
//	fmt.Println(bloomFilter.Public_contains("ad"))
//
//}
